<?xml version='1.0' encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link href="cpip.css" rel="stylesheet" type="text/css" />
    <title>File: /Users/paulross/dev/Python-3.6.2/Include/pyfpe.h</title>
  </head>
  <body>
    <h1>File: /Users/paulross/dev/Python-3.6.2/Include/pyfpe.h</h1>
    <p>Green shading in the line number column
means the source is part of the translation unit, red means it is conditionally excluded.
Highlighted line numbers link to the translation unit page. Highlighted macros link to
the macro page.</p>
    <pre><a name="1" /><span class="True">       1:</span> <span class="f">#</span><span class="n">ifndef</span> <a href="macros_noref.html#_UHlfUFlGUEVfSF8w"><span class="b">Py_PYFPE_H</span></a>
<a name="2" /><span class="True">       2:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlfUFlGUEVfSF8w"><span class="b">Py_PYFPE_H</span></a>
<a name="3" /><span class="False">       3:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">__cplusplus</span>
<a name="4" /><span class="False">       4:</span> <span class="m">extern</span> <span class="e">&quot;C&quot;</span> <span class="f">{</span>
<a name="5" /><span class="True">       5:</span> <span class="f">#</span><span class="n">endif</span>
<a name="6" /><span class="True">       6:</span> <span class="k">/*</span>
<a name="7" /><span class="True">       7:</span> <span class="k">     ---------------------------------------------------------------------</span>
<a name="8" /><span class="True">       8:</span> <span class="k">    /                       Copyright (c) 1996.                           \</span>
<a name="9" /><span class="True">       9:</span> <span class="k">   |          The Regents of the University of California.                 |</span>
<a name="10" /><span class="True">      10:</span> <span class="k">   |                        All rights reserved.                           |</span>
<a name="11" /><span class="True">      11:</span> <span class="k">   |                                                                       |</span>
<a name="12" /><span class="True">      12:</span> <span class="k">   |   Permission to use, copy, modify, and distribute this software for   |</span>
<a name="13" /><span class="True">      13:</span> <span class="k">   |   any purpose without fee is hereby granted, provided that this en-   |</span>
<a name="14" /><span class="True">      14:</span> <span class="k">   |   tire notice is included in all copies of any software which is or   |</span>
<a name="15" /><span class="True">      15:</span> <span class="k">   |   includes  a  copy  or  modification  of  this software and in all   |</span>
<a name="16" /><span class="True">      16:</span> <span class="k">   |   copies of the supporting documentation for such software.           |</span>
<a name="17" /><span class="True">      17:</span> <span class="k">   |                                                                       |</span>
<a name="18" /><span class="True">      18:</span> <span class="k">   |   This  work was produced at the University of California, Lawrence   |</span>
<a name="19" /><span class="True">      19:</span> <span class="k">   |   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |</span>
<a name="20" /><span class="True">      20:</span> <span class="k">   |   between  the  U.S.  Department  of  Energy and The Regents of the   |</span>
<a name="21" /><span class="True">      21:</span> <span class="k">   |   University of California for the operation of UC LLNL.              |</span>
<a name="22" /><span class="True">      22:</span> <span class="k">   |                                                                       |</span>
<a name="23" /><span class="True">      23:</span> <span class="k">   |                              DISCLAIMER                               |</span>
<a name="24" /><span class="True">      24:</span> <span class="k">   |                                                                       |</span>
<a name="25" /><span class="True">      25:</span> <span class="k">   |   This  software was prepared as an account of work sponsored by an   |</span>
<a name="26" /><span class="True">      26:</span> <span class="k">   |   agency of the United States Government. Neither the United States   |</span>
<a name="27" /><span class="True">      27:</span> <span class="k">   |   Government  nor the University of California nor any of their em-   |</span>
<a name="28" /><span class="True">      28:</span> <span class="k">   |   ployees, makes any warranty, express or implied, or  assumes  any   |</span>
<a name="29" /><span class="True">      29:</span> <span class="k">   |   liability  or  responsibility  for the accuracy, completeness, or   |</span>
<a name="30" /><span class="True">      30:</span> <span class="k">   |   usefulness of any information,  apparatus,  product,  or  process   |</span>
<a name="31" /><span class="True">      31:</span> <span class="k">   |   disclosed,   or  represents  that  its  use  would  not  infringe   |</span>
<a name="32" /><span class="True">      32:</span> <span class="k">   |   privately-owned rights. Reference herein to any specific  commer-   |</span>
<a name="33" /><span class="True">      33:</span> <span class="k">   |   cial  products,  process,  or  service  by trade name, trademark,   |</span>
<a name="34" /><span class="True">      34:</span> <span class="k">   |   manufacturer, or otherwise, does not  necessarily  constitute  or   |</span>
<a name="35" /><span class="True">      35:</span> <span class="k">   |   imply  its endorsement, recommendation, or favoring by the United   |</span>
<a name="36" /><span class="True">      36:</span> <span class="k">   |   States Government or the University of California. The views  and   |</span>
<a name="37" /><span class="True">      37:</span> <span class="k">   |   opinions  of authors expressed herein do not necessarily state or   |</span>
<a name="38" /><span class="True">      38:</span> <span class="k">   |   reflect those of the United States Government or  the  University   |</span>
<a name="39" /><span class="True">      39:</span> <span class="k">   |   of  California,  and shall not be used for advertising or product   |</span>
<a name="40" /><span class="True">      40:</span> <span class="k">    \  endorsement purposes.                                              /</span>
<a name="41" /><span class="True">      41:</span> <span class="k">     ---------------------------------------------------------------------</span>
<a name="42" /><span class="True">      42:</span> <span class="k">*/</span>
<a name="43" /><span class="True">      43:</span> 
<a name="44" /><span class="True">      44:</span> <span class="k">/*</span>
<a name="45" /><span class="True">      45:</span> <span class="k"> *       Define macros for handling SIGFPE.</span>
<a name="46" /><span class="True">      46:</span> <span class="k"> *       Lee Busby, LLNL, November, 1996</span>
<a name="47" /><span class="True">      47:</span> <span class="k"> *       busby1@llnl.gov</span>
<a name="48" /><span class="True">      48:</span> <span class="k"> *</span>
<a name="49" /><span class="True">      49:</span> <span class="k"> *********************************************</span>
<a name="50" /><span class="True">      50:</span> <span class="k"> * Overview of the system for handling SIGFPE:</span>
<a name="51" /><span class="True">      51:</span> <span class="k"> *</span>
<a name="52" /><span class="True">      52:</span> <span class="k"> * This file (Include/pyfpe.h) defines a couple of &quot;wrapper&quot; macros for</span>
<a name="53" /><span class="True">      53:</span> <span class="k"> * insertion into your Python C code of choice. Their proper use is</span>
<a name="54" /><span class="True">      54:</span> <span class="k"> * discussed below. The file Python/pyfpe.c defines a pair of global</span>
<a name="55" /><span class="True">      55:</span> <span class="k"> * variables PyFPE_jbuf and PyFPE_counter which are used by the signal</span>
<a name="56" /><span class="True">      56:</span> <span class="k"> * handler for SIGFPE to decide if a particular exception was protected</span>
<a name="57" /><span class="True">      57:</span> <span class="k"> * by the macros. The signal handler itself, and code for enabling the</span>
<a name="58" /><span class="True">      58:</span> <span class="k"> * generation of SIGFPE in the first place, is in a (new) Python module</span>
<a name="59" /><span class="True">      59:</span> <span class="k"> * named fpectl. This module is standard in every respect. It can be loaded</span>
<a name="60" /><span class="True">      60:</span> <span class="k"> * either statically or dynamically as you choose, and like any other</span>
<a name="61" /><span class="True">      61:</span> <span class="k"> * Python module, has no effect until you import it.</span>
<a name="62" /><span class="True">      62:</span> <span class="k"> *</span>
<a name="63" /><span class="True">      63:</span> <span class="k"> * In the general case, there are three steps toward handling SIGFPE in any</span>
<a name="64" /><span class="True">      64:</span> <span class="k"> * Python code:</span>
<a name="65" /><span class="True">      65:</span> <span class="k"> *</span>
<a name="66" /><span class="True">      66:</span> <span class="k"> * 1) Add the *_PROTECT macros to your C code as required to protect</span>
<a name="67" /><span class="True">      67:</span> <span class="k"> *    dangerous floating point sections.</span>
<a name="68" /><span class="True">      68:</span> <span class="k"> *</span>
<a name="69" /><span class="True">      69:</span> <span class="k"> * 2) Turn on the inclusion of the code by adding the ``--with-fpectl&apos;&apos;</span>
<a name="70" /><span class="True">      70:</span> <span class="k"> *    flag at the time you run configure.  If the fpectl or other modules</span>
<a name="71" /><span class="True">      71:</span> <span class="k"> *    which use the *_PROTECT macros are to be dynamically loaded, be</span>
<a name="72" /><span class="True">      72:</span> <span class="k"> *    sure they are compiled with WANT_SIGFPE_HANDLER defined.</span>
<a name="73" /><span class="True">      73:</span> <span class="k"> *</span>
<a name="74" /><span class="True">      74:</span> <span class="k"> * 3) When python is built and running, import fpectl, and execute</span>
<a name="75" /><span class="True">      75:</span> <span class="k"> *    fpectl.turnon_sigfpe(). This sets up the signal handler and enables</span>
<a name="76" /><span class="True">      76:</span> <span class="k"> *    generation of SIGFPE whenever an exception occurs. From this point</span>
<a name="77" /><span class="True">      77:</span> <span class="k"> *    on, any properly trapped SIGFPE should result in the Python</span>
<a name="78" /><span class="True">      78:</span> <span class="k"> *    FloatingPointError exception.</span>
<a name="79" /><span class="True">      79:</span> <span class="k"> *</span>
<a name="80" /><span class="True">      80:</span> <span class="k"> * Step 1 has been done already for the Python kernel code, and should be</span>
<a name="81" /><span class="True">      81:</span> <span class="k"> * done soon for the NumPy array package.  Step 2 is usually done once at</span>
<a name="82" /><span class="True">      82:</span> <span class="k"> * python install time. Python&apos;s behavior with respect to SIGFPE is not</span>
<a name="83" /><span class="True">      83:</span> <span class="k"> * changed unless you also do step 3. Thus you can control this new</span>
<a name="84" /><span class="True">      84:</span> <span class="k"> * facility at compile time, or run time, or both.</span>
<a name="85" /><span class="True">      85:</span> <span class="k"> *</span>
<a name="86" /><span class="True">      86:</span> <span class="k"> ********************************</span>
<a name="87" /><span class="True">      87:</span> <span class="k"> * Using the macros in your code:</span>
<a name="88" /><span class="True">      88:</span> <span class="k"> *</span>
<a name="89" /><span class="True">      89:</span> <span class="k"> * static PyObject *foobar(PyObject *self,PyObject *args)</span>
<a name="90" /><span class="True">      90:</span> <span class="k"> * {</span>
<a name="91" /><span class="True">      91:</span> <span class="k"> *     ....</span>
<a name="92" /><span class="True">      92:</span> <span class="k"> *     PyFPE_START_PROTECT(&quot;Error in foobar&quot;, return 0)</span>
<a name="93" /><span class="True">      93:</span> <span class="k"> *     result = dangerous_op(somearg1, somearg2, ...);</span>
<a name="94" /><span class="True">      94:</span> <span class="k"> *     PyFPE_END_PROTECT(result)</span>
<a name="95" /><span class="True">      95:</span> <span class="k"> *     ....</span>
<a name="96" /><span class="True">      96:</span> <span class="k"> * }</span>
<a name="97" /><span class="True">      97:</span> <span class="k"> *</span>
<a name="98" /><span class="True">      98:</span> <span class="k"> * If a floating point error occurs in dangerous_op, foobar returns 0 (NULL),</span>
<a name="99" /><span class="True">      99:</span> <span class="k"> * after setting the associated value of the FloatingPointError exception to</span>
<a name="100" /><span class="True">     100:</span> <span class="k"> * &quot;Error in foobar&quot;. ``Dangerous_op&apos;&apos; can be a single operation, or a block</span>
<a name="101" /><span class="True">     101:</span> <span class="k"> * of code, function calls, or any combination, so long as no alternate</span>
<a name="102" /><span class="True">     102:</span> <span class="k"> * return is possible before the PyFPE_END_PROTECT macro is reached.</span>
<a name="103" /><span class="True">     103:</span> <span class="k"> *</span>
<a name="104" /><span class="True">     104:</span> <span class="k"> * The macros can only be used in a function context where an error return</span>
<a name="105" /><span class="True">     105:</span> <span class="k"> * can be recognized as signaling a Python exception. (Generally, most</span>
<a name="106" /><span class="True">     106:</span> <span class="k"> * functions that return a PyObject * will qualify.)</span>
<a name="107" /><span class="True">     107:</span> <span class="k"> *</span>
<a name="108" /><span class="True">     108:</span> <span class="k"> * Guido&apos;s original design suggestion for PyFPE_START_PROTECT and</span>
<a name="109" /><span class="True">     109:</span> <span class="k"> * PyFPE_END_PROTECT had them open and close a local block, with a locally</span>
<a name="110" /><span class="True">     110:</span> <span class="k"> * defined jmp_buf and jmp_buf pointer. This would allow recursive nesting</span>
<a name="111" /><span class="True">     111:</span> <span class="k"> * of the macros. The Ansi C standard makes it clear that such local</span>
<a name="112" /><span class="True">     112:</span> <span class="k"> * variables need to be declared with the &quot;volatile&quot; type qualifier to keep</span>
<a name="113" /><span class="True">     113:</span> <span class="k"> * setjmp from corrupting their values. Some current implementations seem</span>
<a name="114" /><span class="True">     114:</span> <span class="k"> * to be more restrictive. For example, the HPUX man page for setjmp says</span>
<a name="115" /><span class="True">     115:</span> <span class="k"> *</span>
<a name="116" /><span class="True">     116:</span> <span class="k"> *   Upon the return from a setjmp() call caused by a longjmp(), the</span>
<a name="117" /><span class="True">     117:</span> <span class="k"> *   values of any non-static local variables belonging to the routine</span>
<a name="118" /><span class="True">     118:</span> <span class="k"> *   from which setjmp() was called are undefined. Code which depends on</span>
<a name="119" /><span class="True">     119:</span> <span class="k"> *   such values is not guaranteed to be portable.</span>
<a name="120" /><span class="True">     120:</span> <span class="k"> *</span>
<a name="121" /><span class="True">     121:</span> <span class="k"> * I therefore decided on a more limited form of nesting, using a counter</span>
<a name="122" /><span class="True">     122:</span> <span class="k"> * variable (PyFPE_counter) to keep track of any recursion.  If an exception</span>
<a name="123" /><span class="True">     123:</span> <span class="k"> * occurs in an ``inner&apos;&apos; pair of macros, the return will apparently</span>
<a name="124" /><span class="True">     124:</span> <span class="k"> * come from the outermost level.</span>
<a name="125" /><span class="True">     125:</span> <span class="k"> *</span>
<a name="126" /><span class="True">     126:</span> <span class="k"> */</span>
<a name="127" /><span class="True">     127:</span> 
<a name="128" /><span class="False">     128:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">WANT_SIGFPE_HANDLER</span>
<a name="129" /><span class="False">     129:</span> <span class="f">#</span><span class="n">include</span> <span class="f">&lt;</span><span class="b">signal</span><span class="f">.</span><span class="b">h</span><span class="f">&gt;</span>
<a name="130" /><span class="False">     130:</span> <span class="f">#</span><span class="n">include</span> <span class="f">&lt;</span><span class="b">setjmp</span><span class="f">.</span><span class="b">h</span><span class="f">&gt;</span>
<a name="131" /><span class="False">     131:</span> <span class="f">#</span><span class="n">include</span> <span class="f">&lt;</span><span class="b">math</span><span class="f">.</span><span class="b">h</span><span class="f">&gt;</span>
<a name="132" /><span class="False">     132:</span> <span class="m">extern</span> <span class="b">jmp_buf</span> <span class="b">PyFPE_jbuf</span><span class="f">;</span>
<a name="133" /><span class="False">     133:</span> <span class="m">extern</span> <span class="m">int</span> <span class="b">PyFPE_counter</span><span class="f">;</span>
<a name="134" /><span class="False">     134:</span> <span class="m">extern</span> <span class="m">double</span> <span class="b">PyFPE_dummy</span><span class="f">(</span><span class="m">void</span> <span class="f">*</span><span class="f">)</span><span class="f">;</span>
<a name="135" /><span class="False">     135:</span> 
<a name="136" /><span class="False">     136:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlGUEVfU1RBUlRfUFJPVEVDVF8w"><span class="b">PyFPE_START_PROTECT</span></a><span class="f">(</span><span class="b">err_string</span><span class="f">,</span> <span class="b">leave_stmt</span><span class="f">)</span> \
<a name="137" /><span class="False">     137:</span> <span class="m">if</span> <span class="f">(</span><span class="f">!</span><span class="b">PyFPE_counter</span><span class="f">++</span> <span class="f">&amp;&amp;</span> <span class="b">setjmp</span><span class="f">(</span><span class="b">PyFPE_jbuf</span><span class="f">)</span><span class="f">)</span> <span class="f">{</span> \
<a name="138" /><span class="False">     138:</span>     <span class="b">PyErr_SetString</span><span class="f">(</span><span class="b">PyExc_FloatingPointError</span><span class="f">,</span> <span class="b">err_string</span><span class="f">)</span><span class="f">;</span> \
<a name="139" /><span class="False">     139:</span>     <span class="b">PyFPE_counter</span> <span class="f">=</span> <span class="c">0</span><span class="f">;</span> \
<a name="140" /><span class="False">     140:</span>     <span class="b">leave_stmt</span><span class="f">;</span> \
<a name="141" /><span class="False">     141:</span> <span class="f">}</span>
<a name="142" /><span class="False">     142:</span> 
<a name="143" /><span class="False">     143:</span> <span class="k">/*</span>
<a name="144" /><span class="False">     144:</span> <span class="k"> * This (following) is a heck of a way to decrement a counter. However,</span>
<a name="145" /><span class="False">     145:</span> <span class="k"> * unless the macro argument is provided, code optimizers will sometimes move</span>
<a name="146" /><span class="False">     146:</span> <span class="k"> * this statement so that it gets executed *before* the unsafe expression</span>
<a name="147" /><span class="False">     147:</span> <span class="k"> * which we&apos;re trying to protect.  That pretty well messes things up,</span>
<a name="148" /><span class="False">     148:</span> <span class="k"> * of course.</span>
<a name="149" /><span class="False">     149:</span> <span class="k"> *</span>
<a name="150" /><span class="False">     150:</span> <span class="k"> * If the expression(s) you&apos;re trying to protect don&apos;t happen to return a</span>
<a name="151" /><span class="False">     151:</span> <span class="k"> * value, you will need to manufacture a dummy result just to preserve the</span>
<a name="152" /><span class="False">     152:</span> <span class="k"> * correct ordering of statements.  Note that the macro passes the address</span>
<a name="153" /><span class="False">     153:</span> <span class="k"> * of its argument (so you need to give it something which is addressable).</span>
<a name="154" /><span class="False">     154:</span> <span class="k"> * If your expression returns multiple results, pass the last such result</span>
<a name="155" /><span class="False">     155:</span> <span class="k"> * to PyFPE_END_PROTECT.</span>
<a name="156" /><span class="False">     156:</span> <span class="k"> *</span>
<a name="157" /><span class="False">     157:</span> <span class="k"> * Note that PyFPE_dummy returns a double, which is cast to int.</span>
<a name="158" /><span class="False">     158:</span> <span class="k"> * This seeming insanity is to tickle the Floating Point Unit (FPU).</span>
<a name="159" /><span class="False">     159:</span> <span class="k"> * If an exception has occurred in a preceding floating point operation,</span>
<a name="160" /><span class="False">     160:</span> <span class="k"> * some architectures (notably Intel 80x86) will not deliver the interrupt</span>
<a name="161" /><span class="False">     161:</span> <span class="k"> * until the *next* floating point operation.  This is painful if you&apos;ve</span>
<a name="162" /><span class="False">     162:</span> <span class="k"> * already decremented PyFPE_counter.</span>
<a name="163" /><span class="False">     163:</span> <span class="k"> */</span>
<a name="164" /><span class="False">     164:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlGUEVfRU5EX1BST1RFQ1RfMA__"><span class="b">PyFPE_END_PROTECT</span></a><span class="f">(</span><span class="b">v</span><span class="f">)</span> <span class="b">PyFPE_counter</span> <span class="f">-=</span> <span class="f">(</span><span class="m">int</span><span class="f">)</span><span class="b">PyFPE_dummy</span><span class="f">(</span><span class="f">&amp;</span><span class="f">(</span><span class="b">v</span><span class="f">)</span><span class="f">)</span><span class="f">;</span>
<a name="165" /><span class="False">     165:</span> 
<a name="166" /><span class="True">     166:</span> <span class="f">#</span><span class="n">else</span>
<a name="167" /><span class="True">     167:</span> 
<a name="168" /><span class="True">     168:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlGUEVfU1RBUlRfUFJPVEVDVF8w"><span class="b">PyFPE_START_PROTECT</span></a><span class="f">(</span><span class="b">err_string</span><span class="f">,</span> <span class="b">leave_stmt</span><span class="f">)</span>
<a name="169" /><span class="True">     169:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlGUEVfRU5EX1BST1RFQ1RfMA__"><span class="b">PyFPE_END_PROTECT</span></a><span class="f">(</span><span class="b">v</span><span class="f">)</span>
<a name="170" /><span class="True">     170:</span> 
<a name="171" /><span class="True">     171:</span> <span class="f">#</span><span class="n">endif</span>
<a name="172" /><span class="True">     172:</span> 
<a name="173" /><span class="False">     173:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">__cplusplus</span>
<a name="174" /><span class="False">     174:</span> <span class="f">}</span>
<a name="175" /><span class="True">     175:</span> <span class="f">#</span><span class="n">endif</span>
<a name="176" /><span class="True">     176:</span> <span class="f">#</span><span class="n">endif</span> <span class="k">/* !Py_PYFPE_H */</span>
<a name="177" /><span class="True">     177:</span> </pre>
  </body>
</html>
